package com.ruoyi.datastatistics.service.impl;

import java.math.RoundingMode;
import java.util.*;
import java.util.concurrent.atomic.AtomicLong;
import java.util.stream.Collectors;

import cn.hutool.core.collection.CollUtil;
import cn.hutool.core.util.NumberUtil;
import cn.hutool.core.util.StrUtil;
import cn.hutool.json.JSONUtil;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.ruoyi.basedata.domain.MeterSheets;
import com.ruoyi.basedata.service.IMeterSheetsService;
import com.ruoyi.common.utils.PageUtil;
import com.ruoyi.datastatistics.domain.MeterReadingRate;
import com.ruoyi.datastatistics.mapper.MeterReadingRateMapper;
import com.ruoyi.datastatistics.model.MeterReadingRateQueryModel;
import com.ruoyi.datastatistics.model.MeterReadingRateResultModel;
import com.ruoyi.datastatistics.service.IMeterReadingRateService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

/**
 * 抄表率统计Service业务层处理
 *
 * @author gdqt
 * @date 2024-03-06
 */
@Service
public class MeterReadingRateServiceImpl implements IMeterReadingRateService {
    @Autowired
    private MeterReadingRateMapper meterReadingRateMapper;

    @Autowired
    private IMeterSheetsService meterSheetsService;

    /**
     * 查询抄表率统计
     *
     * @param id 抄表率统计主键
     * @return 抄表率统计
     */
    @Override
    public MeterReadingRate selectMeterReadingRateById(Long id) {
        return meterReadingRateMapper.selectMeterReadingRateById(id);
    }

    /**
     * 查询抄表率统计列表
     *
     * @param meterReadingRate 抄表率统计
     * @return 抄表率统计
     */
    @Override
    public List<MeterReadingRate> selectMeterReadingRateList(MeterReadingRate meterReadingRate) {
        return meterReadingRateMapper.selectMeterReadingRateList(meterReadingRate);
    }

    /**
     * 新增抄表率统计
     *
     * @param meterReadingRate 抄表率统计
     * @return 结果
     */
    @Override
    public int insertMeterReadingRate(MeterReadingRate meterReadingRate) {
        return meterReadingRateMapper.insertMeterReadingRate(meterReadingRate);
    }

    /**
     * 修改抄表率统计
     *
     * @param meterReadingRate 抄表率统计
     * @return 结果
     */
    @Override
    public int updateMeterReadingRate(MeterReadingRate meterReadingRate) {
        return meterReadingRateMapper.updateMeterReadingRate(meterReadingRate);
    }

    /**
     * 批量删除抄表率统计
     *
     * @param ids 需要删除的抄表率统计主键
     * @return 结果
     */
    @Override
    public int deleteMeterReadingRateByIds(Long[] ids) {
        return meterReadingRateMapper.deleteMeterReadingRateByIds(ids);
    }

    /**
     * 删除抄表率统计信息
     *
     * @param id 抄表率统计主键
     * @return 结果
     */
    @Override
    public int deleteMeterReadingRateById(Long id) {
        return meterReadingRateMapper.deleteMeterReadingRateById(id);
    }

    @Override
    public List<MeterReadingRate> selectMeterReadingRateByQueryModel(MeterReadingRateQueryModel model) {
        LambdaQueryWrapper<MeterReadingRate> queryWrapper = new LambdaQueryWrapper<>();
        if (StrUtil.isNotEmpty(model.getSheetsCode())) {
            ArrayList<String> sheetsCodeList = CollUtil.toList(model.getSheetsCode().split(","));
            queryWrapper.in(MeterReadingRate::getSheetsCode, sheetsCodeList);
        }

        if (model.getDateSpan() == 1) {
            queryWrapper.ge(MeterReadingRate::getYesterDay, model.getRateFrom());
            queryWrapper.le(MeterReadingRate::getYesterDay, model.getRateTo());
        } else if (model.getDateSpan() == 7) {
            queryWrapper.ge(MeterReadingRate::getNearlySevenDays, model.getRateFrom());
            queryWrapper.le(MeterReadingRate::getNearlySevenDays, model.getRateTo());
        } else {
            queryWrapper.ge(MeterReadingRate::getNearlyDays, model.getRateFrom());
            queryWrapper.le(MeterReadingRate::getNearlyDays, model.getRateTo());
        }

        return meterReadingRateMapper.selectList(queryWrapper);
    }

    @Override
    public Map<String, Object> getReadingRateList(MeterReadingRateQueryModel model) {
        Map<String, Object> resultMap = new HashMap<>();
        List<MeterReadingRateResultModel> resultModelList = new ArrayList<>();

        List<MeterSheets> meterSheetsList = meterSheetsService.selectMeterSheetsBySheetsCode(model.getSheetsCode());

        AtomicLong totalAll = new AtomicLong(0);
        AtomicLong countAll = new AtomicLong(0);

        List<MeterReadingRate> meterReadingRateList = this.selectMeterReadingRateByQueryModel(model);
        if (CollUtil.isNotEmpty(meterReadingRateList)) {
            meterReadingRateList.forEach(item -> {
                MeterReadingRateResultModel resultModel = new MeterReadingRateResultModel();
                resultModel.setSheetsCode(item.getSheetsCode());
                MeterSheets meterSheets = meterSheetsList.stream().filter(item1 -> item1.getSheetsCode().equals(item.getSheetsCode())).findFirst().orElse(null);
                resultModel.setSheetsName(meterSheets == null ? null : meterSheets.getSheetsName());
                // 只显示小表区域
                if (meterSheets == null || !Objects.equals(meterSheets.getDeviceType(), 1)) {
                    return;
                }
                long total = 0, count = 0;
                MeterReadingRate target = meterReadingRateList.stream().filter(record -> record.getSheetsCode().equals(item.getSheetsCode())).findFirst().orElse(null);
                if (target != null) {
                    if (model.getDateSpan() == 1) {
                        resultModel.setTotal(target.getYesterDayY());
                        resultModel.setCount(target.getYesterDayS());
                        resultModel.setRate(target.getYesterDay().doubleValue());
                    } else if (model.getDateSpan() == 7) {
                        resultModel.setTotal(target.getNearlySevenDaysY());
                        resultModel.setCount(target.getNearlySevenDaysS());
                        resultModel.setRate(target.getNearlySevenDays().doubleValue());
                    } else {
                        resultModel.setTotal(target.getNearlyDaysY());
                        resultModel.setCount(target.getNearlyDaysS());
                        resultModel.setRate(target.getNearlyDays().doubleValue());
                    }
                    total = resultModel.getTotal();
                    count = resultModel.getCount();
                }

                resultModelList.add(resultModel);
                totalAll.addAndGet(total);
                countAll.addAndGet(count);
            });

            Comparator<MeterReadingRateResultModel> comparator = Comparator.comparing(MeterReadingRateResultModel::getSheetsCode);
            if ("sheetsName".equals(model.getOrderByColumn())) {
                comparator = Comparator.comparing(MeterReadingRateResultModel::getSheetsName);
            }
            if ("total".equals(model.getOrderByColumn())) {
                comparator = Comparator.comparing(MeterReadingRateResultModel::getTotal);
            }
            if ("count".equals(model.getOrderByColumn())) {
                comparator = Comparator.comparing(MeterReadingRateResultModel::getCount);
            }
            if ("rate".equals(model.getOrderByColumn())) {
                comparator = Comparator.comparing(MeterReadingRateResultModel::getRate);
            }
            if ("descending".equals(model.getIsAsc())) {
                comparator = comparator.reversed();
            }

            resultModelList.sort(comparator);
        }

        double rateAll = totalAll.get() == 0 ? 0D : countAll.get() * 1.0D / totalAll.get() * 100;
        resultMap.put("dataTotal", resultModelList.size());
        resultMap.put("dataRows", PageUtil.startPage(resultModelList, model.getPageNum(), model.getPageSize()));
        resultMap.put("totalAll", totalAll);
        resultMap.put("countAll", countAll);
        resultMap.put("rateAll", NumberUtil.round(rateAll, 2, RoundingMode.HALF_UP).doubleValue());

        return resultMap;
    }
}
